package main

import (
	"context"
	"fmt"
	"log"
	"time"

	"gitee.com/doove/ansible-go"
)

func main() {
	fmt.Println("=== Ansible-Go 基础使用示例 ===")
	
	// 示例 1: 基础 ping 测试
	basicPingExample()
	
	// 示例 2: Docker 容器管理
	dockerContainerExample()
	
	// 示例 3: 文件操作
	fileOperationsExample()
	
	// 示例 4: 服务管理
	serviceManagementExample()
	
	// 示例 5: Playbook 执行
	playbookExample()
	
	// 示例 6: 结果解析
	resultParsingExample()
	
	// 示例 7: 错误处理
	errorHandlingExample()
}

func basicPingExample() {
	fmt.Println("\n--- 示例 1: 基础 ping 测试 ---")
	
	// 创建简单的 inventory
	inventory := "localhost,"
	
	// 创建 Ansible 实例
	ans := ansible.NewAnsible("ansible", inventory, []string{"localhost"}, context.Background())
	
	// 配置输出格式和警告
	ans.SetOutJson().CloseWarnings()
	
	// 执行 ping 模块
	stdout, stderr, err := ans.Ping()
	if err != nil {
		fmt.Printf("Ping 失败: %v\n", err)
		if ansible.IsAnsibleError(err) {
			if ansibleErr, ok := ansible.GetAnsibleError(err); ok {
				fmt.Printf("详细错误: %s\n", string(ansibleErr.Stderr))
			}
		}
		return
	}
	
	fmt.Printf("Ping 成功!\n输出: %s\n", string(stdout))
}

func dockerContainerExample() {
	fmt.Println("\n--- 示例 2: Docker 容器管理 ---")
	
	// 创建 Docker SSH 容器的 inventory
	inventory := ansible.NewDockerInventoryBuilder().
		AddDockerSSHContainer("web-server", "root", "password", 2222).
		AddDockerSSHContainer("db-server", "postgres", "secret", 2223).
		SetDockerDefaults()
	
	tempFile, err := inventory.ToTempFile()
	if err != nil {
		fmt.Printf("创建 inventory 文件失败: %v\n", err)
		return
	}
	
	fmt.Printf("创建的 inventory 文件: %s\n", tempFile)
	fmt.Printf("Inventory 内容:\n%s\n", inventory.Build())
	
	// 创建 Ansible 实例
	ans := ansible.NewAnsible("ansible", tempFile, []string{"all"}, context.Background())
	ans.SetOutJson().CloseWarnings()
	
	// 尝试连接测试（这会失败，因为没有真实的容器）
	_, _, err = ans.Ping()
	if err != nil {
		fmt.Printf("Docker 容器连接测试失败（预期）: %v\n", err)
	}
}

func fileOperationsExample() {
	fmt.Println("\n--- 示例 3: 文件操作 ---")
	
	inventory := "localhost,"
	ans := ansible.NewAnsible("ansible", inventory, []string{"localhost"}, context.Background())
	ans.SetOutJson().CloseWarnings()
	
	// 文件复制示例
	fmt.Println("文件复制示例:")
	_, _, err := ans.Copy("/etc/hosts", "/tmp/hosts_backup", ansible.ModuleOptions{
		"backup": "yes",
		"owner":  "root",
		"mode":   "0644",
	})
	if err != nil {
		fmt.Printf("文件复制失败: %v\n", err)
	}
	
	// 创建目录示例
	fmt.Println("创建目录示例:")
	_, _, err = ans.File("/tmp/testdir", ansible.ModuleOptions{
		"state": "directory",
		"mode":  "0755",
	})
	if err != nil {
		fmt.Printf("创建目录失败: %v\n", err)
	}
	
	// 行编辑示例
	fmt.Println("行编辑示例:")
	_, _, err = ans.Lineinfile("/etc/hosts", "127.0.0.1 test.local", ansible.ModuleOptions{
		"backup": "yes",
	})
	if err != nil {
		fmt.Printf("行编辑失败: %v\n", err)
	}
}

func serviceManagementExample() {
	fmt.Println("\n--- 示例 4: 服务管理 ---")
	
	inventory := "localhost,"
	ans := ansible.NewAnsible("ansible", inventory, []string{"localhost"}, context.Background())
	ans.SetOutJson().CloseWarnings()
	
	// 启动服务
	fmt.Println("启动 nginx 服务:")
	_, _, err := ans.Service("nginx", "started", ansible.ModuleOptions{
		"enabled": "yes",
	})
	if err != nil {
		fmt.Printf("启动服务失败: %v\n", err)
	}
	
	// 安装包
	fmt.Println("安装软件包:")
	_, _, err = ans.Package("vim", "present")
	if err != nil {
		fmt.Printf("安装软件包失败: %v\n", err)
	}
	
	// 用户管理
	fmt.Println("创建用户:")
	_, _, err = ans.User("deploy", ansible.ModuleOptions{
		"state": "present",
		"shell": "/bin/bash",
		"home":  "/home/deploy",
	})
	if err != nil {
		fmt.Printf("创建用户失败: %v\n", err)
	}
}

func playbookExample() {
	fmt.Println("\n--- 示例 5: Playbook 执行 ---")
	
	inventory := "localhost,"
	playbook := ansible.NewPlaybook("ansible-playbook", inventory, context.Background())
	
	// 配置 playbook
	playbook.SetOutJson().CloseWarnings().SetTags("web")
	
	// 从字节数组执行 playbook
	playbookContent := []byte(`
---
- hosts: localhost
  connection: local
  gather_facts: no
  tasks:
    - name: 显示消息
      debug:
        msg: "Hello from ansible-go!"
      tags: web
    
    - name: 创建测试文件
      file:
        path: /tmp/ansible-go-test
        state: touch
      tags: web
`)
	
	fmt.Println("执行 Playbook:")
	stdout, stderr, err := playbook.RunWithBytes(playbookContent)
	if err != nil {
		fmt.Printf("Playbook 执行失败: %v\n", err)
		if len(stderr) > 0 {
			fmt.Printf("错误输出: %s\n", string(stderr))
		}
	} else {
		fmt.Printf("Playbook 执行成功!\n输出: %s\n", string(stdout))
	}
}

func resultParsingExample() {
	fmt.Println("\n--- 示例 6: 结果解析 ---")
	
	inventory := "localhost,"
	ans := ansible.NewAnsible("ansible", inventory, []string{"localhost"}, context.Background())
	ans.SetOutJson().CloseWarnings()
	
	// 使用解析结果的方法
	result, err := ans.RunWithModuleParsed("setup")
	if err != nil {
		fmt.Printf("执行失败: %v\n", err)
		return
	}
	
	fmt.Printf("主机: %s\n", result.Host)
	fmt.Printf("状态: %s\n", result.Status)
	fmt.Printf("是否成功: %v\n", result.IsSuccess())
	fmt.Printf("摘要: %s\n", result.Summary())
	
	// 获取系统信息
	if osFamily, exists := result.GetFactString("ansible_os_family"); exists {
		fmt.Printf("操作系统家族: %s\n", osFamily)
	}
	
	if distribution, exists := result.GetFactString("ansible_distribution"); exists {
		fmt.Printf("发行版: %s\n", distribution)
	}
}

func errorHandlingExample() {
	fmt.Println("\n--- 示例 7: 错误处理 ---")
	
	inventory := "nonexistent-host,"
	ans := ansible.NewAnsible("ansible", inventory, []string{"nonexistent-host"}, context.Background())
	ans.SetOutJson().CloseWarnings()
	
	// 故意执行一个会失败的命令
	stdout, stderr, err := ans.Ping()
	if err != nil {
		fmt.Printf("命令执行失败: %v\n", err)
		
		// 检查是否是 Ansible 错误
		if ansible.IsAnsibleError(err) {
			if ansibleErr, ok := ansible.GetAnsibleError(err); ok {
				fmt.Printf("操作: %s\n", ansibleErr.Op)
				fmt.Printf("命令: %s\n", ansibleErr.Command)
				fmt.Printf("标准输出: %s\n", string(ansibleErr.Stdout))
				fmt.Printf("标准错误: %s\n", string(ansibleErr.Stderr))
			}
		}
	} else {
		fmt.Printf("意外成功: %s\n", string(stdout))
	}
}

// 高级配置示例
func advancedConfigExample() {
	fmt.Println("\n--- 高级配置示例 ---")
	
	// 创建自定义配置
	config := ansible.DefaultConfig().
		WithBinPath("/usr/local/bin/ansible").
		WithTimeout(30 * time.Second).
		WithOutputFormat(ansible.OutputFormatJSON).
		WithPTY(true).
		WithForceColor(true).
		WithSuppressWarnings(true).
		SetEnv("ANSIBLE_HOST_KEY_CHECKING", "False")
	
	// 创建自定义日志记录器
	logger := ansible.NewJSONLogger(slog.LevelDebug)
	config.WithLogger(logger)
	
	fmt.Printf("配置创建完成: %+v\n", config)
}

// 并发执行示例
func concurrentExample() {
	fmt.Println("\n--- 并发执行示例 ---")
	
	inventory := "localhost,"
	
	// 创建多个 Ansible 实例并发执行
	done := make(chan bool, 3)
	
	for i := 0; i < 3; i++ {
		go func(id int) {
			defer func() { done <- true }()
			
			ans := ansible.NewAnsible("ansible", inventory, []string{"localhost"}, context.Background())
			ans.SetOutJson().CloseWarnings()
			
			_, _, err := ans.Shell(fmt.Sprintf("echo 'Worker %d'", id))
			if err != nil {
				fmt.Printf("Worker %d 失败: %v\n", id, err)
			} else {
				fmt.Printf("Worker %d 成功\n", id)
			}
		}(i)
	}
	
	// 等待所有任务完成
	for i := 0; i < 3; i++ {
		<-done
	}
	
	fmt.Println("所有并发任务完成")
}
